A number of optimizations are possible for the geometry subsystem:
This section describes how to draw geometry with optimal primitives. Consider these guidelines to optimize drawing:
Connected primitives are desirable because they reduce the amount of data and the amount of per-polygon or per-edge work done by OpenGL.
Concave and self-intersecting polygons must be tessellated by GLU before they can be drawn, and are therefore prohibitively expensive. Nonplanar polygons and polygons with large numbers of vertices are more likely to exhibit shading artifacts.
If your database has polygons that are not well-behaved, perform an initial one-time pass over the database to change the troublemakers into well-behaved polygons and use the new database for rendering. You can store the results in OpenGL display lists. Using connected primitives results in additional gains.
Polygon rates can be affected directly by the number of normals or colors sent per polygon. Setting a color or normal per vertex, regardless of the glShadeModel() used, may be slower than setting only a color per polygon, because of the time spent sending the extra data and resetting the current color. The number of normals and colors per polygon also directly affects the size of a display list containing the object.
Vertex arrays are available in OpenGL 1.1 (see "OpenGL 1.1 Vertex Arrays"). They offer the following benefits:
One possible disadvantage to vertex arrays over using glBegin()/glEnd() is that it may require additional memory usage.
If you use glBegin()/glEnd() instead of glDrawArrays() or glDrawElements() calls, put as many vertices as possible between the glBegin() and the glEnd(). This amortizes the cost of the call and also makes it easier to batch vertices.
Note that in situations where vertices are shared, it makes sense to lock them down for optimum performance. See "The Compiled Vertex Arrays Extension."
This section discusses ways of reducing per-vertex costs.
For optimum performance, use flat shading whenever possible. This reduces the number of lighting computations from one per vertex to one per primitive, and also reduces the amount of data that must be processed for each primitive. This is particularly important for high-performance line drawing.
OpenGL offers many features that create sophisticated effects with excellent performance. However, these features have some performance cost, compared to drawing the same scene without them. Use these features only where their effects, performance, and quality are justified.
Once a feature has been turned on, it can slow the transform rate even when it has no visible effect.
For example, the use of fog can slow the transform rate of polygons even when the polygons are too close to show fog, and even when the fog density is set to zero. For these conditions, turn off fog explicitly with
glDisable(GL_FOG)
OpenGL offers a large selection of lighting features: The penalties some features carry may vary depending on the hardware you're running on. Be prepared to experiment with the lighting configuration.
As a general rule, use the simplest possible lighting model, a single infinite light with an infinite viewer. For some local effects, try replacing local lights with infinite lights and a local viewer.
Use the following settings for peak performance lighting:
In addition, follow these guidelines to achieve peak lighting performance:
Local lights are noticeably more expensive than infinite lights.
Changing material parameters can be expensive. If you need to change the material parameters many times per frame, consider rearranging the scene traversal to minimize material changes. Also consider using glColorMaterial() or glIndexMaterialSGI() to change specific parameters automatically, rather than using glMaterial() to change parameters explicitly.
The following code fragment illustrates how to change ambient and diffuse material parameters at every polygon or at every vertex:
glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
...
/* Set ambient and diffuse material parameters: */
glColor4f(red, green, blue, alpha);
/* Draw triangles: */
glBegin(GL_TRIANGLES);
...
glEnd();
This section describes advanced techniques for tuning transform-limited drawing. Follow these guidelines to draw objects with complex surface characteristics:
Consider drawing an image of a complex object by texturing it onto a single polygon. Set alpha values to zero in the texture outside the image of the object. (The edges of the object can be antialiased by using alpha values between zero and one.) Orient the polygon to face the viewer. To prevent pixels with zero alpha values in the textured polygon from being drawn, call
glAlphaFunc(GL_NOTEQUAL, 0.0)
This effect is often used to create objects like trees that have complex edges or many holes through which the background should be visible (or both), such as trees.